You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
241 lines
10 KiB
241 lines
10 KiB
import Link from "next/link";
|
|
import { getDictionary, type Locale } from "@/lib/site-content";
|
|
|
|
export default async function HomePage({
|
|
params,
|
|
}: {
|
|
params: Promise<{ locale: string }>;
|
|
}) {
|
|
const { locale } = await params;
|
|
const typedLocale = locale as Locale;
|
|
const dictionary = getDictionary(typedLocale);
|
|
const isZh = typedLocale === "zh";
|
|
|
|
const integrationTitle = isZh ? "popiartcli 接入原生流程" : "Native integration flow for popiartcli";
|
|
const integrationSubtitle = isZh
|
|
? "按照以下步骤,将 popiartcli 无缝接入你的 agent 工作流"
|
|
: "Follow these steps to plug popiartcli directly into your coding agent workflow.";
|
|
const stepOneTitle = isZh ? "复制安装指令到你的环境" : "Copy the install command into your environment";
|
|
const stepOneHint = isZh
|
|
? "先安装 CLI,再登录获取产品层 key"
|
|
: "Install the CLI first, then sign in to get the product-layer key.";
|
|
const stepTwoTitle = isZh
|
|
? "执行 bootstrap,让 PopiArt 在你的 agent 环境中可发现"
|
|
: "Run bootstrap so PopiArt becomes discoverable in your agent environment.";
|
|
const stepTwoHint = isZh
|
|
? "生成 completion、默认 discovery profile,并接入 Codex / OpenCode / OpenClaw"
|
|
: "Generate completion, default discovery profiles, and wire into Codex, OpenCode, or OpenClaw.";
|
|
const stepThreeTitle = isZh
|
|
? "如需轮换或重置产品层 token,请前往控制台管理密钥"
|
|
: "Rotate or reset the product-layer token from the console when needed.";
|
|
const stepThreeHint = isZh
|
|
? "使用 API key 与 session,而不是把 provider 密钥直接分发到本地环境"
|
|
: "Use API keys and sessions instead of distributing raw provider credentials to local machines.";
|
|
const stepFourTitle = isZh
|
|
? "了解更多功能及服务使用须知,请查看开发者文档"
|
|
: "Read the developer docs for capabilities, runtime behavior, and usage guidance.";
|
|
const docsAction = isZh ? "查看开发者文档" : "Open developer docs";
|
|
const installAction = isZh ? "登录" : "Sign in";
|
|
const bootstrapAction = isZh ? "查看 Quick Start" : "Open Quick Start";
|
|
const consoleAction = isZh ? "前往控制台" : "Open console";
|
|
const sceneAction = isZh ? "了解更多" : "Learn more";
|
|
|
|
return (
|
|
<div className="page-stack">
|
|
<section className="hero-panel hero-panel-reference">
|
|
<div className="hero-copy">
|
|
<div className="eyebrow">{dictionary.home.tag}</div>
|
|
<h1>{dictionary.home.title}</h1>
|
|
<p className="hero-description">{dictionary.home.subtitle}</p>
|
|
<div className="hero-actions">
|
|
<Link className="button button-dark" href={`/${locale}#integration`}>
|
|
{dictionary.home.primaryCta}
|
|
</Link>
|
|
<Link className="button button-light" href={`/${locale}/docs`}>
|
|
{dictionary.home.secondaryCta}
|
|
</Link>
|
|
</div>
|
|
<div className="hero-proof">
|
|
<span>{dictionary.home.freeTrial}</span>
|
|
<span>{dictionary.home.socialProof}</span>
|
|
</div>
|
|
</div>
|
|
<div className="hero-stage hero-stage-reference">
|
|
<div className="hero-pattern" aria-hidden="true">
|
|
{Array.from({ length: 5 }).map((_, row) => (
|
|
<div className="hero-pattern-row" key={row}>
|
|
{dictionary.home.heroPhrases.map((phrase) => (
|
|
<span key={`${row}-${phrase}`}>{phrase}</span>
|
|
))}
|
|
</div>
|
|
))}
|
|
</div>
|
|
<div className="stage-card stage-card-floating stage-card-primary">
|
|
<div className="stage-label">{dictionary.home.stageLabel}</div>
|
|
<div className="stage-stat">{dictionary.home.stageValue}</div>
|
|
<p>{dictionary.home.stageDescription}</p>
|
|
</div>
|
|
</div>
|
|
</section>
|
|
|
|
<section className="section-panel">
|
|
<div className="section-heading">
|
|
<div className="eyebrow">{dictionary.home.scenesTag}</div>
|
|
<h2>{dictionary.home.scenesTitle}</h2>
|
|
<p>{dictionary.home.scenesSubtitle}</p>
|
|
</div>
|
|
<div className="card-grid card-grid-three">
|
|
{dictionary.home.scenes.map((scene, index) => (
|
|
<article className="feature-card scene-card" key={scene.name}>
|
|
<div className={`scene-visual scene-visual-${(index % 6) + 1}`}>
|
|
<span className="card-kicker">{scene.category}</span>
|
|
</div>
|
|
<span className="card-kicker">{scene.category}</span>
|
|
<h3>{scene.name}</h3>
|
|
<p>{scene.description}</p>
|
|
<Link className="scene-link" href={`/${locale}/docs`}>
|
|
{sceneAction}
|
|
</Link>
|
|
</article>
|
|
))}
|
|
</div>
|
|
</section>
|
|
|
|
<section className="integration-shell" id="integration">
|
|
<div className="integration-heading">
|
|
<div className="eyebrow">{dictionary.home.flowTag}</div>
|
|
<h2>{integrationTitle}</h2>
|
|
<p>{integrationSubtitle}</p>
|
|
</div>
|
|
<div className="integration-steps">
|
|
<article className="integration-step-card">
|
|
<div className="integration-step-head">
|
|
<span className="integration-step-dot" aria-hidden="true" />
|
|
<span className="integration-step-label">STEP 1</span>
|
|
<h3>{stepOneTitle}</h3>
|
|
</div>
|
|
<div className="integration-step-body">
|
|
<pre>
|
|
<code>{dictionary.home.installMethods[0]?.command}</code>
|
|
</pre>
|
|
<div className="integration-method-pills">
|
|
{dictionary.home.installMethods.map((method) => (
|
|
<span className="pill" key={method.name}>
|
|
{method.name}
|
|
</span>
|
|
))}
|
|
</div>
|
|
<div className="integration-step-actions">
|
|
<span>{stepOneHint}</span>
|
|
<Link className="button button-dark" href={`/${locale}/login`}>
|
|
{installAction}
|
|
</Link>
|
|
</div>
|
|
</div>
|
|
</article>
|
|
|
|
<article className="integration-step-card">
|
|
<div className="integration-step-head">
|
|
<span className="integration-step-dot" aria-hidden="true" />
|
|
<span className="integration-step-label">STEP 2</span>
|
|
<h3>{stepTwoTitle}</h3>
|
|
</div>
|
|
<div className="integration-step-body">
|
|
<pre>
|
|
<code>{dictionary.home.bootstrapCommand}</code>
|
|
</pre>
|
|
<div className="integration-step-actions">
|
|
<span>{stepTwoHint}</span>
|
|
<Link className="button button-light integration-docs-link" href={`/${locale}/docs`}>
|
|
{bootstrapAction}
|
|
<span aria-hidden="true">→</span>
|
|
</Link>
|
|
</div>
|
|
</div>
|
|
</article>
|
|
|
|
<article className="integration-step-card">
|
|
<div className="integration-step-head">
|
|
<span className="integration-step-dot" aria-hidden="true" />
|
|
<span className="integration-step-label">OPENCLAW</span>
|
|
<h3>{dictionary.home.agentSkillTitle}</h3>
|
|
</div>
|
|
<div className="integration-step-body">
|
|
<p>{dictionary.home.agentSkillDescription}</p>
|
|
<pre>
|
|
<code>{dictionary.home.agentSkillCommand}</code>
|
|
</pre>
|
|
</div>
|
|
</article>
|
|
|
|
<article className="integration-step-card">
|
|
<div className="integration-step-head">
|
|
<span className="integration-step-dot" aria-hidden="true" />
|
|
<span className="integration-step-label">STEP 3</span>
|
|
<h3>{stepThreeTitle}</h3>
|
|
</div>
|
|
<div className="integration-step-body integration-step-body-compact">
|
|
<div className="integration-step-actions">
|
|
<span>{stepThreeHint}</span>
|
|
<Link className="button button-light integration-docs-link" href={`/${locale}/console`}>
|
|
{consoleAction}
|
|
<span aria-hidden="true">→</span>
|
|
</Link>
|
|
</div>
|
|
</div>
|
|
</article>
|
|
|
|
<article className="integration-step-card">
|
|
<div className="integration-step-head">
|
|
<span className="integration-step-dot" aria-hidden="true" />
|
|
<span className="integration-step-label">STEP 4</span>
|
|
<h3>{stepFourTitle}</h3>
|
|
</div>
|
|
<div className="integration-step-body integration-step-body-compact">
|
|
<Link className="button button-light integration-docs-link" href={`/${locale}/docs`}>
|
|
{docsAction}
|
|
<span aria-hidden="true">→</span>
|
|
</Link>
|
|
</div>
|
|
</article>
|
|
</div>
|
|
</section>
|
|
|
|
<section className="section-panel section-panel-accent">
|
|
<div className="section-heading">
|
|
<div className="eyebrow">{dictionary.pricing.tag}</div>
|
|
<h2>{dictionary.pricing.title}</h2>
|
|
<p>{dictionary.pricing.subtitle}</p>
|
|
</div>
|
|
<div className="pricing-grid">
|
|
{dictionary.pricing.plans.map((plan) => (
|
|
<article
|
|
className={`pricing-card ${plan.highlight ? "pricing-card-highlight" : ""}`}
|
|
key={plan.name}
|
|
>
|
|
<div className="pricing-top">
|
|
<div>
|
|
<div className="card-kicker">{plan.badge}</div>
|
|
<h3>{plan.name}</h3>
|
|
<p className="pricing-summary">{plan.summary}</p>
|
|
</div>
|
|
<div className="price-line">
|
|
<strong>{plan.price}</strong>
|
|
<span>{plan.cadence}</span>
|
|
</div>
|
|
</div>
|
|
<ul className="bullet-list">
|
|
{plan.features.map((feature) => (
|
|
<li key={feature}>{feature}</li>
|
|
))}
|
|
</ul>
|
|
<Link className={`button ${plan.highlight ? "button-dark" : "button-light"}`} href={`/${locale}/pricing`}>
|
|
{plan.cta}
|
|
</Link>
|
|
</article>
|
|
))}
|
|
</div>
|
|
</section>
|
|
</div>
|
|
);
|
|
}
|
|
|